/**
 * jsgig.screen - Functions related to screen access and control.
 * 
 * Depends: jQuery, jsgig
 */
if (!jsgig) {
  throw new Error("jsgig must be included before jsgig.screen can be created.");
}
if (!jsgig.screen) { jsgig.screen = (function() {
var my = {};
  
// Private constants

var _CONTAINER = "body";
var _SIZE = [640, 480];
var _SCALE = 1;
var _BGCOLOR = "#000";

// Private variables

var _container = _CONTAINER;
var _size = _SIZE.slice();
var _scale = _SCALE;
var _element = null;

/**
 * Return the selector for the screen's containing element.
 */
my.getContainer = function getContainer() {
  return _container;
}

/**
 * Set the screen's containing element via jquery selector.
 * 
 * If the screen has already been created, it is removed from its current
 * container and moved to the indicated container.
 * 
 * If no parameter is passed then the current container selector is assumed.
 */ 
my.setContainer = function setContainer(cont) {
  var oldcont = my.getContainer();
  if (!cont)
    cont = oldcont
  else
    _container = cont;
  if (_element) {
    $(_element).detach();
    $(cont).append(_element);
  }
}

/**
 * Return the current screen size setting in pixels.
 * The value returned is a copy of the internal [width, height] array.
 */
my.getSize = function getSize() {
  return _size.slice()
}

/**
 * Set the current screen size in pixels using a [width, height] pair.
 * 
 * If the screen has already been created then the screen element's size is set
 * to the given value.
 * 
 * If no parameter is passed then the current size value is assumed.
 * 
 * The value stored is a copy of the given array.
 */
my.setSize = function setSize(size) {
  if (!size)
    size = my.getSize()
  else
    _size = size.slice();
  if (_element) {
    $(_element).width(size[0]).height(size[1]);
  }
}

/**
 * Return the scaling multiplier that is applied to the screen element.
 * This is a single number that is applied to both dimensions.
 */
my.getScale = function getScale() {
  return _scale
}

/**
* Set the scaling multiplier that is applied to the screen element.
* 
*   screen.setScale([scale]);
* 
* This is a single number that is applied to both dimensions of the screen. The
* size of the screen element in the browser window for each dimension will be
* equal to the screen's size (as indicated by screen.getSize()) times the scale
* value.
* 
* If the screen has already been created then CSS is applied to it to set the
* current scale factor. Otherwise, this value is stored internally and applied
* once the screen is created.
* 
* Autoscaling/Scale To Fit:
* 
* It is possible to set the scaling to automatically fit the screen to its
* container.
* 
* If no parameter is passed then the current scale value is assumed.
*/
my.setScale = function setScale(scale) {
  if (scale === null || scale === undefined) {
    scale = my.getScale();
  }
  else {
    scale = parseFloat(scale);
  }
  if (!util.isNumber(scale) || scale < 0) {
    throw new TypeError(
      "scale must be a number >= 0 or null. (Got " + scale + ")"
    );
  }
  var oldscale = _scale;
  _scale = scale;
  if (oldscale == 0) {
    $(window).off({resize: _scaleToFit});
  }
  if (scale != 0) {
    _setScaleInternal(scale);
  }
  else {
    $(window).on({resize: _scaleToFit});
    _scaleToFit();
  }
}

// This is used by the setScale method to allow automatic scaling.
function _scaleToFit() {
  var el = _element;
  if (el) {
    var sw = _size[0];
    var sh = _size[1];
    var parent = $(el).parent();
    var pw = parent.width();
    var ph = parent.height();
    var scale = ((ph/pw) > (sh/sw)) ? (pw/sw) : (ph/sh);
    _setScaleInternal(scale);
  }
}

// Used internally by the setScale() and _scaleToFit() functions
function _setScaleInternal(scale) {
  var scalestr = "scale(" + scale + ")";
  // $(_element)
    // .css("margin-left",
      // ($(my.getContainer()).width() - my.getSize()[0] * scale) * 0.5 + "px")
    // .css("margin-top",
      // ($(my.getContainer()).height() - my.getSize()[1] * scale) * 0.5 + "px")
    // .css("transform", scalestr)
    // .css("-moz-transform", scalestr)
    // .css("-ms-transform", scalestr)
    // .css("-o-transform", scalestr)
    // .css("-webkit-transform", scalestr);
  $(_element).css({
    marginLeft:
      ($(my.getContainer()).width() - my.getSize()[0] * scale) * 0.5 + "px",
    marginTop:
      ($(my.getContainer()).height() - my.getSize()[1] * scale) * 0.5 + "px",
    transform: scalestr,
    MozTransform: scalestr,
    MsTransform: scalestr,
    OTransform: scalestr,
    WebkitTransform: scalestr
  });
}

/**
 * Returns current background color of the screen.
 * Shorthand for $(jsgig.screen.getElement()).css("background-color");
 */
my.getBGColor = function getBGColor() {
  return $(getElement()).css("background-color");
}

/**
 * Apply a background color to the screen.
 * 
 * Shorthand for $(jsgig.screen.getElement()).css({backgroundColor: bgcolor});
 * If no value is passed, the background color is not changed.
 */
my.setBGColor = function setBGColor(bgcolor) {
  if (bgcolor !== undefined)
    $(getElement()).css({backgroundColor: bgcolor});
}

/**
 * Return the screen element.
 * This will be null if the screen hasn't been created yet.
 */
my.getElement = function getElement() {
  return _element;
}

/**
 * Create or re-create the screen.
 * 
 *   jsgig.screen.create([container[, size[, scale[, bgcolor]]]]);
 * 
 * This will create a new DOM element (currently a <div>) and put it into the 
 * element indicated by the current jQuery selector for the screen container.
 * 
 * If a screen already exists, a new screen element is created anyway and the
 * contents of the old screen element are moved into the new one. The old
 * screen will  * be detached from the DOM and the new one will take its
 * place.
 * 
 * You may pass parameters to the create() function to set the screen
 * configuration. These same settings can also be set individually at any time
 * using the other methods of the jsgig.screen object. Any option not passed
 * or set to null will cause that setting to remain unchanged or to use the 
 * default if no setting has yet been applied. See the functions associated
 * with the parameters for mor details.
 * 
 * The new screen element will be returned.
 */
my.create = function create(container, size, scale, bgcolor) {
  // Safely detach previous element
  var oldelement = _element;
  if (oldelement) {
    $(oldelement).detach();
  }
  
  // Create new screen element with CSS formatting optimized for 
  var el$ = _element = $("<div>");
  _element = el$[0];
  el$
    .attr({id: "jsgig"})
    .css("margin", "0")
    .css("padding", "0")
    .css("background-color", _BGCOLOR)
    .css("overflow", "hidden")
    .css("content-overflow", "hidden")
    .css("transform-origin", "0 0")
    .css("-ms-transform-origin", "0 0")
    .css("-moz-transform-origin", "0 0")
    .css("-webkit-transform-origin", "0 0")
    .css("-o-transform-origin", "0 0")
    .css("image-rendering", "optimizeSpeed")
    .css("image-rendering", "-moz-crisp-edges")
    .css("image-rendering", "-webkit-optimize-contrast")
    .css("-ms-interpolation-mode", "nearest-neighbor");
  
  // Apply given settings and/or default settings
  my.setContainer(container);
  my.setSize(size);
  my.setScale(scale);
  my.setBGColor(bgcolor);
  
  // Move elements from the old screen to the new, if necessary
  if (oldelement) {
    $(oldelement).children().each(function(i){
      this.detach();
      el$.append(this);
    });
  }
}

// End of module `jsgig.screen`
return my; }) ();}